package me.caofeng.service;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import me.caofeng.dao.SmsCodeMapper;
import me.caofeng.dao.UserMapper;
import me.caofeng.enums.ResponseCode;
import me.caofeng.pojo.Response;
import me.caofeng.pojo.SmsCode;
import me.caofeng.service.api.INoticeService;
import me.caofeng.util.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.TimeUnit;

/**
 * Copyright © 2017曹峰. All rights reserved.
 *
 * @Prject: mall
 * @Package: me.caofeng.service
 * @Description:
 * @Author: 曹峰 blog.caofeng.me
 * @Date: 2017-06-18 17:39
 * @Version: V1.0
 */
@Service
@Transactional
public class NoticeService implements INoticeService {
    @Autowired
    private SmsCodeMapper smsCodeMapper;

    @Autowired
    private UserMapper userMapper;

    private static Logger LOGGER = LogManager.getLogger(NoticeService.class);

    private Cache<String, SmsCode> smsCodeCache = CacheBuilder
            .newBuilder()
            .expireAfterWrite(10, TimeUnit.MINUTES)
            .build();

    @Override
    @SuppressWarnings("unchecked")
    public Response sendSmsCode(String phone) {
        if (!CheckUtil.isPhone(phone)) {
            return Response.response(ResponseCode.ILLEGAL_ARGUMENT,
                    "手机号不正确", null);
        }

        SmsCode codeCache = null;
        codeCache = smsCodeCache.getIfPresent(phone);
        if (null != codeCache) {
            return Response.response(ResponseCode.SUCCESS,
                    "验证码还有效", null);
        }

        String code = MD5Util.generaVerifyCode();
        // todo 向短信平台请求发送短信验证码
        codeCache = new SmsCode(null, code,0);
        smsCodeCache.put(phone, codeCache);
        smsCodeMapper.addSmsCode(code,phone);
        LOGGER.debug(phone+" 发送的短信验证码为 " + code);
        return Response.response(ResponseCode.SUCCESS,
                ResponseCode.SUCCESS.getMessage(), null);
    }

    @Override
    public Response<String> verifySmsCode(SmsCode smsCode,String userId) {
        if (null == smsCode){
            return Response.response(ResponseCode.ILLEGAL_ARGUMENT,"请输入正确的验证码",null);
        }
        String phone = smsCode.getPhone();
        String code = smsCode.getCode();
        if (!CheckUtil.isPhone(phone) || !CheckUtil.isDigit(code)) {
            return Response.response(ResponseCode.ILLEGAL_ARGUMENT,
                    "请输入正确的验证码", null);
        }

        SmsCode codeCache = null;
        codeCache = smsCodeCache.getIfPresent(phone);

        if (null == codeCache) {
            //该手机号没有发送过验证码
            return Response.response(ResponseCode.ILLEGAL_ARGUMENT,
                    "请先获取验证码", null);
        }

        Integer count = codeCache.getCount();

        if (null == count) {
            //验证码错误，默认错误次数为0
            codeCache.setCount(1);
            return Response.response(ResponseCode.ILLEGAL_ARGUMENT,
                    "验证码错误", null);
        }

        if (count > 5) {
            //错误次数超过5次，验证失效
            smsCodeCache.invalidate(phone);
            return Response.response(ResponseCode.ILLEGAL_ARGUMENT
                    , "验证码已失效，请重新获取", null);
        }

        if (code.equals(codeCache.getCode())) {
            //验证码正确,生成jwt给客户端
            //检测用户是否注册，如果已经注册，返回其user id
            userId = null == userId ? userMapper.isExits(phone): userId;
            String token = JwtUtil.createToken(phone,Constant.SMS_CODE_EXPIRE,userId);
            smsCodeCache.invalidate(phone);
            return Response.response(ResponseCode.SUCCESS, "验证成功", token);
        }else {
            codeCache.setCount(count+1);
            smsCodeCache.put(phone,codeCache);
            return Response.response(ResponseCode.ILLEGAL_ARGUMENT,
                    "验证码错误", null);
        }


    }
}
